// This file is part of Visuals, and is based on Winamp's AVS plugin. 
// Copyright 2005 Nullsoft, Inc.
// Copyright 2011 Scott Sibley

var coords = new Array();
function TranslateCoords(n, pitch) {
	coords[0] = n % pitch // column
	coords[1] = (n - coords[0]) / pitch // row
	return coords
}

function Color2RGB(color) {
	var a = (color & 0xff000000) >> 24;
	var r = (color & 0xff0000) >> 16;
	var g = (color & 0xff00) >> 8
	var b = (color & 0xff);
	return [r, g, b, a]
}

function RGB2Color(r, g, b, a) {
	if(a != 0 && !a) a = 0xff;
	return (b & 0xff) | ((g << 8) & 0xff00) | ((r << 16) & 0xff0000) | ((a << 24) & 0xff000000);
}

function Color16_8x2(color) {
		var left = (color & 0xf70) >> 8;
		var right = color & 0x0F7;
		return [left, right];
}
function Color8x2_16(l, r) {
	return ((l << 8) & 0xf70) | (r & 0x0f7);
}

var tmp = new Array();
function Color32_8x4(color) {
	tmp[0] = (color & 0xff000000) >> 24;
	tmp[1] = (color & 0xff0000) >> 16;
	tmp[2] = (color & 0xff00) >> 8;
	tmp[3] = (color & 0xff);
	return tmp;
}

		//fbout[i] = ((of[i * 2] << 8) & 0xf70) | (of[i * 2 + 1] & 0x0f7); //Color8x2_16(of[i * 2], of[i * 2 + 1]);	
function Color8x4_32(b1, b2, b3, b4) {
	var c = (b1 << 24) & 0xff000000;;
	c = c | (b2 << 16) & 0xff0000;
	c = c | (b3 << 8) & 0xff00;
	c = c | b4 & 0xff;
	return c;
}

/*
function toHex(N) {
	if (N==null) return "0";
	N=parseInt(N); if (N==0 || isNaN(N)) return "0";
	N=Math.max(0,N); N=Math.min(N,127); N=Math.round(N);
	return "0123456789ABCDEF".charAt((N >> 16)%16) + "0123456789ABCDEF".charAt(N%16);;
}*/

function RGBtoCSS(R, G, B, A) {
	return "rgba(" + R + ", " + G + ", " + B + ", " + A + ");"; 
}


function buffer_line(buffer, x0, y0, x1, y1, color, pitch) {
	var dy = y1 - y0;
	var dx = x1 - x0;
	var stepx, stepy;

	if (dy < 0) { dy = -dy;  stepy = -pitch } else { stepy = pitch; }
	if (dx < 0) { dx = -dx;  stepx = -1; } else { stepx = 1; }
	dy = dy << 1;
	dx = dx << 1;

	y0 = y0 * pitch
	y1 = y1 * pitch
	buffer[x0+y0] = color
	if (dx > dy) {
		var fraction = dy - (dx >> 1)
		while (x0 != x1) {
			if (fraction >= 0) {
				y0 = y0 + stepy
				fraction = fraction - dx
			}
			x0 = x0 + stepx
			fraction = fraction + dy
			buffer[x0+y0] = color
		}
	} else {
		var fraction = dx - (dy >> 1)
		while (y0 != y1) {
			if (fraction >= 0) {
				x0 = x0 + stepx
				fraction = fraction - dy
			}
			y0 = y0 + stepy
			fraction = fraction + dx
			buffer[x0+y0] = color
		}
	}
}

function buffer_blit_slow(buffer, context, pixel,  width, height) {
	var context = c_canvas.getContext("2d");
	for(var y = 0; y < height; y++) {
		for(var x = 0; x < width; x++) {
			var n = y * width + x
			var c = Color2RGB(buffer[n]);
			context.fillStyle = RGBtoCSS(c[0], c[1], c[2], 0xff);
			context.fillRect(x * pixel, y * pixel, x * pixel + pixel, y * pixel + pixel)
		}
	}
}

function draw_rect(data, n, sizex, sizey, color, pitch) {
	var c = Color2RGB(color);
	pitch*=sizex;
	for( var y = 0; y < sizey; y++) {
		var nn = n * 4;
		for( var x = 0; x < sizex; x++) {
			data[nn++] = c[0];
			data[nn++] = c[1];
			data[nn++] = c[2];
			data[nn++] = 0xff;
		}
		n = n + pitch;
	} 
}

var dummy = document.createElement("canvas");
var dummyctx = dummy.getContext("2d");
/*
var tmpImg = new Image();
var tmpCtx;
var count = 0;
var toggle = true;
function brightness() {
		var img = tmpImg; 
		if(((count++) % 40) == 0) toggle = !toggle;;
		if(toggle && false){ // this eats babies.
			var newimg = Pixastic.process(
				tmpImg,
				"brightness",	// brightness/contrast adjustment

				{		// options object

					"brightness" : 50,	// set brightness option value to 60
					"contrast" : 1,	// set contrast option value to 0.5,
				})
			img = newimg;
		}
		tmpCtx.save();
		
		//tmpCtx.canvas.width = tmpCtx.canvas.width;
		//tmpCtx.scale(xscale, yscale);
	 	tmpCtx.drawImage(img, 0, 0, width * pixel * 5, height * pixel * 5);
		tmpCtx.restore();
}
*/

function buffer_blit(buffer, canvas, width, height) {
	var context = canvas.getContext("2d");
	var imageData = dummyctx.getImageData(0, 0, width * pixel, height * pixel);
	width *= pixel;
	height *= pixel;
	var n = 0;
	for( var y = 0; y < height; y++) {
		for( var x = 0; x < width; x++) {
			var n = y * width + x;
			var c = Color2RGB(buffer[n++]);
			var nn = n * 4;
			imageData.data[nn++] = c[0];
			imageData.data[nn++] = c[1];
			imageData.data[nn++] = c[2]
			imageData.data[nn] = 0xff;
			
		}
		n+=width;
	}
	//if(!redraw) {
		context.putImageData(imageData, 0, 0);
	/*} else {
		dummyctx.putImageData(imageData, 0, 0);	
		tmpImg.onload = brightness;
		tmpCtx = context;
		tmpImg.src = dummy.toDataURL("image/png");
	}*/
}


function clear() {
	var c_canvas = document.getElementById("canvas");
	var context = c_canvas.getContext("2d");
	var imageData = context.getImageData(0, 0, context.canvas.width, context.canvas.height);

	for(i = 0; i < context.canvas.width * context.canvas.height; i++) {
		fbout[i] = bgcolor;
		buffer[i] = bgcolor;
	}
	
	buffer_blit(fbout, c_canvas, pixel, context.canvas.width, context.canvas.height);
}

/*
function zoom_32 (dest, src)
{
	uint32_t *sbuf = visual_video_get_pixels (src);
	uint32_t *dbuf = visual_video_get_pixels (dest);
	var sbuf = src;
	var dbuf = dest;
	var sbufptr = 0;
	var dbufptr = 0;
	int x, y;

	const int spdiff = src->pitch - src->width*src->bpp;
	for (y = 0; y < src->height; y++) {
		dbuf = dest->pixel_rows[y << 1];
		for (x = 0; x < src->width; x++) {
			*(dbuf + dest->width) = *sbuf;
			*(dbuf++) = *sbuf;
			*(dbuf + dest->width) = *sbuf;
			*(dbuf++) = *sbuf;

			sbuf++;
		}

		sbuf += spdiff;
	}

	return VISUAL_OK;
}
*/

var addvar = function(name, val) {
	if(this[name]) return;
	this[name] = val;
	this.variables.push(name);
};

var getvar = function(name) {
	return this[name];
};

var setvar = function(name, val) {
	this[name] = val;
};

var getenv = function() {
	var str = "";
	for(i = 0; i < this.variables.length; i++) {
		var name = this.variables[i];
		str += name + " = " + this[name] + ";"
	}
	return str;
};

var setenv = function() {
	var str = "";
	for(i = 0; i < this.variables.length; i++) {
		var name = this.variables[i];
		str += "this." + name + " = " + name + ";";
	}
	return str;
};

